import numpy as np
import cv2 as cv

cap = cv.VideoCapture('bike.mp4')  # 读取视频文件

while cap.isOpened():  # 循环播放视频文件，同时显示原视频及其对应的灰度图

    ret, frame = cap.read()  # 逐帧读取视频，ret为布尔值，表示是否成功读取帧，frame为当前帧的图像数据
    if not ret:
        print("视频播放结束")
        break

    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)  # 使用cv2.cvtColor()将当前帧的彩色图像转换为灰度图

    fCoef = np.fft.fft2(gray)  # 傅里叶变换得到傅里叶系数
    mag_spec = np.abs(fCoef)
    mag_spec_sorted = np.sort(mag_spec.ravel())  # 对振幅谱进行排序

    # 压缩比0.5
    thresh = mag_spec_sorted[int((1 - 0.5) * gray.size)]  # 计算位置的振幅阈值
    mask = mag_spec > thresh  # 创建掩码，保留振幅大于阈值的频率分量
    fCoef_compressed1 = fCoef * mask  # 使用掩码压缩傅里叶系数（模拟通过网络传输压缩后的系数）
    img_cp1 = np.fft.ifft2(fCoef_compressed1).real  # 使用压缩后的傅里叶系数进行逆傅里叶变换，得到压缩后的图像
    gray1_normalize = cv.normalize(img_cp1, None, 0, 255, cv.NORM_MINMAX, dtype=cv.CV_8U)  # 进行归一化

    # 压缩比0.05
    thresh1 = mag_spec_sorted[int((1 - 0.05) * gray.size)]  # 计算位置的振幅阈值
    mask1 = mag_spec > thresh1  # 创建掩码，保留振幅大于阈值的频率分量
    fCoef_compressed2 = fCoef * mask1  # 使用掩码压缩傅里叶系数（模拟通过网络传输压缩后的系数）
    img_cp2 = np.fft.ifft2(fCoef_compressed2).real  # 使用压缩后的傅里叶系数进行逆傅里叶变换，得到压缩后的图像
    gray2_normalize = cv.normalize(img_cp2, None, 0, 255, cv.NORM_MINMAX, dtype=cv.CV_8U)  # 进行归一化

    cv.imshow('original', gray)  # 在名为"original"的窗口中显示灰度图像
    cv.imshow('0.5', gray1_normalize)  # 在名为"0.5"的窗口中显示压缩比0.5的图像
    cv.imshow('0.05', gray2_normalize)  # 在名为"0.05"的窗口中显示压缩比0.05的图像
    if cv.waitKey(10) == ord('q'):  # 每隔16ms检查一次用户输入，如果按下'q'键，退出循环
        break

cap.release()  # 释放视频捕捉资源
cv.destroyAllWindows()  # 关闭所有的 GUI 窗口